import re
from datetime import datetime
from typing import List, Dict, Any


def parse_table_repair_records(tables_data: List[List[List[str]]]) -> List[Dict[str, Any]]:
    """
    从Word文档表格数据中解析维修记录单信息
    
    Args:
        tables_data: 表格数据，格式为 [表格][行][列]
        
    Returns:
        List[Dict]: 解析出的维修记录单列表
    """
    records = []
    
    for table in tables_data:
        if len(table) < 3:  # 表格行数太少，跳过
            continue
            
        record = {}
        
        # 遍历表格的每一行，寻找字段映射
        for row in table:
            if len(row) < 2:  # 列数太少，跳过
                continue
                
            # 字段映射
            field_mapping = {
                '系统名称': 'system_name',
                '设备名称': 'equipment_name', 
                '故障日期': 'fault_date',
                '设备编号': 'equipment_number',
                '维修厂家名称': 'maintainer_name',
                '厂家联系人及电话': 'contact_phone',
                '完成日期': 'completion_date',
                '确认人': 'confirmer'
            }
            
            # 处理每一行的数据 - 寻找标签和对应的值
            for i in range(len(row)):
                label = row[i].strip()
                if not label:
                    continue
                    
                # 多行文本字段处理
                if '故障描述' in label:
                    record['fault_description'] = clean_multiline_text(label)
                elif '维修方法' in label:
                    record['maintenance_method'] = clean_multiline_text(label)
                elif '更换备件' in label:
                    record['replacement_parts'] = clean_multiline_text(label)
                elif label in field_mapping:
                    # 找到匹配的字段，寻找对应的值
                    field_name = field_mapping[label]
                    value = None
                    
                    # 优先查找下一列的值
                    if i + 1 < len(row):
                        next_value = row[i + 1].strip()
                        if next_value and next_value not in ['', '无', 'N/A', 'n/a'] and next_value != label:
                            value = next_value
                    
                    # 如果下一列没有有效值，对于关键字段不进行其他列查找（保持为空）
                    # 这些字段包括：系统名称、设备名称、故障日期、设备编号、维修厂家名称、厂家联系人及电话、完成日期、确认人
                    protected_fields = ['system_name', 'equipment_name', 'fault_date', 'equipment_number', 
                                      'maintainer_name', 'contact_phone', 'completion_date', 'confirmer']
                    if not value and field_name not in protected_fields:
                        for j in range(len(row)):
                            if j != i:
                                potential_value = row[j].strip()
                                if (potential_value and 
                                    potential_value not in ['', '无', 'N/A', 'n/a'] and 
                                    potential_value != label and
                                    potential_value not in field_mapping and
                                    not any(keyword in potential_value for keyword in ['故障描述', '维修方法', '更换备件'])):
                                    value = potential_value
                                    break
                    
                    if value:
                        if 'date' in field_name:
                            record[field_name] = format_date(value)
                        else:
                            record[field_name] = value
        
        # 如果解析出了有效字段，添加到记录列表
        if record and (record.get('system_name') or record.get('equipment_name')):
            records.append(record)
    
    return records


def clean_multiline_text(text: str) -> str:
    """
    清理多行文本，去除多余的空白字符
    """
    if not text:
        return ''
    # 替换多个连续的空白字符为单个空格
    cleaned = re.sub(r'\s+', ' ', text.strip())
    return cleaned


def format_date(date_str: str) -> str:
    """
    格式化日期字符串
    """
    if not date_str:
        return ''
    
    # 移除常见的非日期字符
    date_str = re.sub(r'[年月日]', '-', date_str)
    date_str = re.sub(r'[-/\s]+', '-', date_str)
    date_str = date_str.strip('-')
    
    # 尝试解析不同的日期格式
    date_patterns = [
        r'(\d{4})-(\d{1,2})-(\d{1,2})',
        r'(\d{4})/(\d{1,2})/(\d{1,2})',
        r'(\d{1,2})-(\d{1,2})-(\d{4})',
        r'(\d{1,2})/(\d{1,2})/(\d{4})'
    ]
    
    for pattern in date_patterns:
        match = re.search(pattern, date_str)
        if match:
            groups = match.groups()
            if len(groups) == 3:
                # 判断年份位置
                if len(groups[0]) == 4:  # YYYY-MM-DD
                    year, month, day = groups
                else:  # DD-MM-YYYY or MM-DD-YYYY
                    day, month, year = groups
                
                try:
                    # 格式化为标准日期格式
                    return f"{year}-{month.zfill(2)}-{day.zfill(2)}"
                except:
                    continue
    
    return date_str


def parse_repair_records_from_text(text: str, tables_data: List[List[List[str]]] = None) -> List[Dict[str, Any]]:
    """
    从Word文档文本中解析维修记录单信息
    
    Args:
        text: Word文档提取的文本内容
        tables_data: Word文档的表格数据
        
    Returns:
        List[Dict]: 解析出的维修记录单列表
    """
    records = []
    
    # 优先尝试从表格数据解析
    if tables_data:
        table_records = parse_table_repair_records(tables_data)
        if table_records:
            return table_records
    
    # 如果表格解析失败或没有表格数据，使用文本解析
    # 清理文本，移除多余的空白字符
    text = re.sub(r'\s+', ' ', text.strip())
    
    # 尝试按"设备维修记录单"分割多个记录
    record_sections = re.split(r'设备维修记录单', text, flags=re.IGNORECASE)
    
    for section in record_sections:
        if len(section.strip()) < 50:  # 跳过太短的片段
            continue
            
        record = parse_single_repair_record(section)
        if record and (record.get('system_name') or record.get('equipment_name')):
            records.append(record)
    
    return records


def parse_single_repair_record(text: str) -> Dict[str, Any]:
    """
    解析单个维修记录单
    
    Args:
        text: 单个记录的文本内容
        
    Returns:
        Dict: 解析出的记录字段
    """
    record = {}
    
    # 定义字段映射和正则表达式
    field_patterns = {
        'system_name': [
            r'系统名称[：:]?\s*([^\n\r，,；;。.]+)',
            r'系统[：:]?\s*([^\n\r，,；;。.]+)'
        ],
        'equipment_name': [
            r'设备名称[：:]?\s*([^\n\r，,；;。.]+)',
            r'设备[：:]?\s*([^\n\r，,；;。.]+)'
        ],
        'fault_date': [
            r'故障日期[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})',
            r'故障时间[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})',
            r'发生日期[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})'
        ],
        'equipment_number': [
            r'设备编号[：:]?\s*([A-Za-z0-9\-_]+)',
            r'编号[：:]?\s*([A-Za-z0-9\-_]+)'
        ],
        'fault_description': [
            r'故障描述[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'故障现象[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'问题描述[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            # 匹配不带字段名的故障描述内容
            r'(?:故障描述[：:]?\s*)?([^\n\r]*(?:故障|异常|问题|失效|损坏|不正常)[^\n\r]*(?:\n[^\n\r]*)*?)(?=\n\s*(?:维修|更换|完成|确认)|$)'
        ],
        'maintainer_name': [
            r'维修厂家名称[：:]?\s*([^\n\r，,；;。.]+)',
            r'维修厂家[：:]?\s*([^\n\r，,；;。.]+)',
            r'维修人员[：:]?\s*([^\n\r，,；;。.]+)'
        ],
        'contact_phone': [
            r'厂家联系人及电话[：:]?\s*([^\n\r]+)',
            r'联系电话[：:]?\s*([^\n\r]+)',
            r'电话[：:]?\s*([^\n\r]+)'
        ],
        'maintenance_method': [
            r'维修方法[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'处理方法[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'解决方案[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            # 匹配不带字段名的维修方法内容
            r'(?:维修方法[：:]?\s*)?([^\n\r]*(?:维修|修理|处理|解决|排查|检查|更换|调整)[^\n\r]*(?:\n[^\n\r]*)*?)(?=\n\s*(?:更换|完成|确认)|$)'
        ],
        'replacement_parts': [
            r'更换备件[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'备件[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            r'零件[：:]?\s*([^\n\r]+(?:\n[^\n\r]*)*?)(?=\n\s*[^\n\r]*[：:]|$)',
            # 匹配不带字段名的更换备件内容
            r'(?:更换备件[：:]?\s*)?([^\n\r]*(?:更换|备件|零件|配件|元件|无相关|无)[^\n\r]*(?:\n[^\n\r]*)*?)(?=\n\s*(?:完成|确认)|$)'
        ],
        'completion_date': [
            r'完成日期[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})',
            r'完成时间[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})',
            r'修复日期[：:]?\s*(\d{4}[/-]\d{1,2}[/-]\d{1,2})'
        ],
        'confirmer': [
            r'确认人[：:]?\s*([^\n\r，,；;。.]+)',
            r'验收人[：:]?\s*([^\n\r，,；;。.]+)',
            r'负责人[：:]?\s*([^\n\r，,；;。.]+)'
        ],
        'attachments': [
            r'附图[：:]?\s*([^\n\r]+)',
            r'附件[：:]?\s*([^\n\r]+)',
            r'相关文件[：:]?\s*([^\n\r]+)'
        ]
    }
    
    # 对每个字段尝试匹配
    for field_name, patterns in field_patterns.items():
        for pattern in patterns:
            match = re.search(pattern, text, re.IGNORECASE | re.MULTILINE)
            if match:
                value = match.group(1).strip()
                if value and value not in ['', '无', 'N/A', 'n/a']:
                    record[field_name] = value
                    break
    
    # 数据清理和格式化
    if 'fault_date' in record:
        record['fault_date'] = format_date(record['fault_date'])
    
    if 'completion_date' in record:
        record['completion_date'] = format_date(record['completion_date'])
    
    # 清理多行文本字段
    for field in ['fault_description', 'maintenance_method', 'replacement_parts']:
        if field in record:
            record[field] = clean_multiline_text(record[field])
    
    return record


def format_date(date_str: str) -> str:
    """
    格式化日期字符串为YYYY-MM-DD格式
    
    Args:
        date_str: 原始日期字符串
        
    Returns:
        str: 格式化后的日期字符串
    """
    try:
        # 尝试不同的日期格式
        date_formats = [
            '%Y/%m/%d', '%Y-%m-%d', '%Y.%m.%d',
            '%Y/%m/%d', '%Y-%m-%d', '%Y.%m.%d'
        ]
        
        for fmt in date_formats:
            try:
                date_obj = datetime.strptime(date_str, fmt)
                return date_obj.strftime('%Y-%m-%d')
            except ValueError:
                continue
        
        # 如果都不匹配，返回原字符串
        return date_str
    except Exception:
        return date_str


def clean_multiline_text(text: str) -> str:
    """
    清理多行文本，移除多余的空白和换行
    
    Args:
        text: 原始文本
        
    Returns:
        str: 清理后的文本
    """
    # 移除多余的空白字符
    text = re.sub(r'\s+', ' ', text.strip())
    
    # 移除字段名前缀
    field_prefixes = [
        r'^故障描述[：:：\s]*',
        r'^维修方法[：:：\s]*', 
        r'^更换备件[：:：\s]*',
        r'^故障现象[：:：\s]*',
        r'^处理方法[：:：\s]*',
        r'^解决方案[：:：\s]*',
        r'^备件[：:：\s]*',
        r'^零件[：:：\s]*'
    ]
    
    for prefix in field_prefixes:
        text = re.sub(prefix, '', text, flags=re.IGNORECASE)
    
    # 移除常见的无意义内容
    text = re.sub(r'^[：:：\s]*', '', text)
    text = re.sub(r'[：:：\s]*$', '', text)
    
    return text


def generate_record_number() -> str:
    """
    生成维修记录编号
    
    Returns:
        str: 格式为YYYYMMDDXXX的记录编号
    """
    from .models import RepairRecord
    
    date_str = datetime.now().strftime('%Y%m%d')
    
    # 查找当天已有的记录数量
    count = RepairRecord.objects.filter(
        record_number__startswith=date_str
    ).count()
    
    return f"{date_str}{count + 1:03d}"